﻿using System;
using System.Text;
using WJ.Infrastructure.Serializer;
using WJ.Infrastructure.WeChat.Model.Pay;

namespace WJ.Infrastructure.WeChat
{
    public class Pay
    {
        /// <summary>
        /// 创建支付订单
        /// </summary>
        /// <param name="openId">用户标识</param>
        /// <param name="orderNo">商户订单号</param>
        /// <param name="totalFee">订单总金额</param>
        /// <param name="goodsDes">商品描述，例如 腾讯充值中心-QQ会员充值</param>
        /// <param name="clientIp">终端IP</param>
        /// <param name="attach">附加数据</param>
        /// <returns></returns>
        public CreateOrderResult CreateOrder(string openId, string orderNo, decimal totalFee, string goodsDes,
            string clientIp,
            string attach,
            LoginType loginType)
        {
            CreateOrderRequest requestParam = new CreateOrderRequest(loginType);
            CreateOrderResult result = new CreateOrderResult();

            requestParam.nonce_str = Guid.NewGuid().ToString().Replace("-", "");
            requestParam.body = goodsDes;
            requestParam.attach = attach;
            requestParam.out_trade_no = orderNo;
            requestParam.total_fee = Convert.ToInt32(totalFee * 100);
            requestParam.spbill_create_ip = clientIp;

            if (loginType == LoginType.WeApp || loginType == LoginType.MWEB)
            {
                requestParam.trade_type = "JSAPI";
            }
//            else if (loginType == LoginType.MWEB)
//            {
//                requestParam.trade_type = "JSAPI";
//
////                requestParam.scene_info =
////                    "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"https://weixin.deyoushenghuo.com\",\"wap_name\": \"得有生活\"}}";
//            }

            requestParam.openid = openId;

            requestParam.sign = Sign.Create(requestParam);


            string response = Http.Post("pay/unifiedorder", Serializer.XML.XmlSerialize(requestParam));

            CreateOrderResponse createOrderResponse = Serializer.XML.XmlDeserialize<CreateOrderResponse>(response);

            Log.Log.Info("[生成预支付交易单]\r\n请求参数:" + requestParam.ToJson() + "\r\n返回信息：" + createOrderResponse.ToJson());

            if (createOrderResponse.return_code != "SUCCESS")
            {
                result.Success = false;
                result.Message = response;
                return result;
            }

            if (createOrderResponse.sign != Sign.Create(createOrderResponse))
            {
                result.Success = false;
                result.Message = "返回结果验签失败";
                return result;
            }

            if (createOrderResponse.result_code != "SUCCESS")
            {
                result.Success = false;
                result.Message = createOrderResponse.err_code_des;
                return result;
            }

            if (createOrderResponse.return_code == "SUCCESS" && createOrderResponse.result_code == "SUCCESS" &&
                !string.IsNullOrEmpty(createOrderResponse.prepay_id))
            {
                result.Success = true;
                if (loginType == LoginType.WeApp || loginType == LoginType.MWEB)
                {
                    result.Message = "prepay_id=" + createOrderResponse.prepay_id;
                }
//                else if (loginType == LoginType.MWEB)
//                {
//                    result.Message = createOrderResponse.mweb_url;
//                }
                return result;
            }

            result.Success = false;
            result.Message = "系统异常";

            return result;
        }

        public WeAppPayParam CreateWeAppPayParam(CreateOrderResult result, LoginType type)
        {
            WeAppPayParam param = new WeAppPayParam(type);

            param.package = result.Message;
            param.paySign = Sign.Create(param, "paySign");

            return param;
        }

        public NotifyResult Notify(string xml)
        {
            StringBuilder logSb = new StringBuilder();
            NotifyResult result = new NotifyResult();

            logSb.Append("[收到支付通知]" + "\r\n参数\r\n" + xml);

            string return_code = "FAIL";
            string return_msg = "";

            Func<string> message = () =>
                $"<xml><return_code><![CDATA[{return_code}]]></return_code><return_msg><![CDATA[{return_msg}]]></return_msg></xml>";

            NotifyParam param = Serializer.XML.XmlDeserialize<NotifyParam>(xml);

            if (param.return_code != "SUCCESS")
            {
                logSb.Append("\r\nreturn_code：" + param.result_code + " return_msg：" + param.return_msg);

                result.Log = logSb.ToString();
                result.Success = false;
                result.Message = message();

                return result;
            }

            if (param.sign != Sign.Create(param))
            {
                logSb.Append("\r\n验签失败");

                return_msg = "验签失败";
                result.Log = logSb.ToString();
                result.Success = false;
                result.Message = message();

                return result;
            }

            if (param.result_code != "SUCCESS")
            {
                logSb.Append("\r\n业务失败" + " err_code：" + param.err_code + " err_code_des：" + param.err_code_des);

                result.Success = false;
            }
            else
            {
                result.Success = true;
            }

            return_code = "SUCCESS";

            result.Log = logSb.ToString();
            result.Message = message();
            result.UserId = Convert.ToInt32(param.attach);
            result.OrderNo = param.out_trade_no;
            result.TransactionNo = param.transaction_id;
            result.PayAmount = Convert.ToInt32(param.total_fee) / 100;

            return result;
        }
    }
}